<?php


namespace LazadaApi\Services;


class LazadaProductService extends BaseLazadaService
{
    /**
     * 使用此API可以创建一个新产品。
     *
     * @see     https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/product/create
     *
     * @param array $productData 数组key 大小写敏感
     *
     * @example $productData
     * {
     *    "Product": {
     *        "PrimaryCategory": "6576",
     *        "SPUId": "",
     *        "AssociatedSku": "",
     *        "Attributes": {
     *            "name": "Cheese forest Indian children's tent play house children's ",
     *            "brand": "No Brand",
     *            "short_description": "商品描述信息",
     *        },
     *        "Skus": [
     *            {
     *                "Sku": {
     *                    "color_family": "White_Not Specified",
     *                    "size": "Not Specified",
     *                    "SellerSku": "1051-12883-White-Not Specified",
     *                    "price": 0,
     *                    "package_weight": 4,
     *                    "package_length": 160,
     *                    "package_width": 12,
     *                    "package_height": 12,
     *                    "Status": "inactive",
     *                    "quantity": 1111,
     *                    "Images": [
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/5554bc476b8167ed8aeeb9f09d4e1993.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/1172eaa46b28776f9ffe944e3c7d4cd8.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/73ff045b9c71873fc8078a14a1218e76.jpg"
     *                        }
     *                    ]
     *                }
     *            },
     *            {
     *                "Sku": {
     *                    "color_family": "Blue_Not Specified",
     *                    "size": "Not Specified",
     *                    "SellerSku": "1051-12883-Blue-Not Specified",
     *                    "price": 0,
     *                    "package_weight": 4,
     *                    "package_length": 160,
     *                    "package_width": 12,
     *                    "package_height": 12,
     *                    "Status": "inactive",
     *                    "quantity": 1111,
     *                    "Images": [
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/5554bc476b8167ed8aeeb9f09d4e1993.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/1172eaa46b28776f9ffe944e3c7d4cd8.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/73ff045b9c71873fc8078a14a1218e76.jpg"
     *                        }
     *                    ]
     *                }
     *            }
     *        ]
     *    }
     *}
     * @return mixed
     * @throws \Exception
     */
    public function createProduct(array $productData)
    {
        $productXML = self::generateXMLPayload($productData);
        $this->addApiParam('payload', $productXML);

        return self::post('/product/create');
    }

    /**
     * 使用此API检索系统中的所有产品品牌。[不需要access_token]
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/brands/get
     *
     * @param int $offset
     * @param int $limit default of 100 is used. The Maximum is 1,000.
     *
     * @return mixed
     * @throws \Exception
     */
    public function getBrands(int $offset = 0, int $limit = 100)
    {
        if ($limit > 1000) {
            $limit = 1000;
        }
        $this->addApiParam('offset', $offset);
        $this->addApiParam('limit', $limit);
        $brands = $this->get('/brands/get');

        return $brands;
    }

    /**
     * 使用此API可以获取指定产品类别的属性列表。[不需要access_token]
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/category/attributes/get
     *
     * @param string $primaryCategoryId
     *
     * @return mixed
     * @throws \Exception
     */
    public function getCategoryAttributes(string $primaryCategoryId)
    {
        $this->addApiParam('primary_category_id', $primaryCategoryId);

        return $this->get('/category/attributes/get');
    }

    /**
     * 使用此API检索系统中所有产品类别的列表。[不需要access_token]
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/category/tree/get
     * @return mixed
     * @throws \Exception
     */
    public function getCategoryTree()
    {
        return $this->get('/category/tree/get');
    }

    /***
     * 通过ItemId或SellerSku获取单个产品。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/product/item/get
     *
     * @param string      $itemId
     * @param string|null $sellerSku
     *
     * @return mixed
     * @throws \Exception
     */
    public function getProductItem(string $itemId, string $sellerSku = null)
    {
        if (!empty($itemId)) {
            $this->addApiParam('item_id', $itemId);
        }
        if (!empty($sellerSku)) {
            $this->addApiParam('seller_sku', $sellerSku);
        }
        $products = $this->get('/product/item/get');

        return $products;
    }

    /**
     * 使用此API可以获取指定产品的详细信息。
     *
     * @see     https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/products/get
     *
     * @param array $queryParams
     *
     * @return mixed
     * @throws \Exception
     * @example $queryParams
     * [
     *     'filter'=> 'live', // Required. Possible values are all, live, inactive, deleted, image-missing, pending,
     *                        // rejected, sold-out. Mandatory.
     *     'update_before'=> '2018-01-01T00:00:00+0800',
     *     'search'=> 'product_name',
     *     'create_before'=> '2018-01-01T00:00:00+0800',
     *     'offset'=> '0',
     *     'create_after'=> '2010-01-01T00:00:00+0800',
     *     'update_after'=> '2010-01-01T00:00:00+0800',
     *     'limit'=> '10',
     *     'options'=> '1',
     *     'sku_seller_list'=> '["39817:01:01", "Apple 6S Black"]',
     * ]
     */
    public function getProducts(array $queryParams = ['filter' => 'live'])
    {
        if (!isset($queryParams['filter']) || empty($queryParams['filter'])) {
            throw new \Exception('查询条件[filter]不能为空', 400);
        }
        $this->setApiParams($queryParams);

        return $this->get('/products/get');
    }

    /**
     * 使用此API可以获取所列出物品的质量控制状态。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/product/qc/status/get
     *
     * @param array $sellerSkus ["005-5060-VIO"]
     * @param int   $offset     0
     * @param int   $limit      100
     *
     * @return mixed
     * @throws \Exception
     */
    public function getQcStatus(array $sellerSkus, int $offset = 0, int $limit = 100)
    {
        $this->addApiParam('offset', $offset);
        $this->addApiParam('limit', $limit);
        $this->addApiParam('seller_skus', $sellerSkus);

        return $this->get('/product/qc/status/get');
    }

    /**
     * 使用此API可以从系统获取 通过 MigrateImages API 批量迁移第三方图片到Lazada平台API的结果。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/image/response/get
     *
     * @param string $batchId 1e0bb81415173896232054839e
     *
     * @return mixed
     * @throws \Exception
     */
    public function getResponse(string $batchId)
    {
        $this->addApiParam('batch_id', $batchId);

        return $this->get('/image/response/get');
    }

    /**
     * 使用此API将单个图像从外部站点迁移到Lazada站点。允许的图像格式为JPG和PNG。图像文件的最大为1MB。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/image/migrate
     *
     * @param string $sourceImageUrl http://pic4.nipic.com/20091217/3885730_124701000519_2.jpg
     *
     * @return mixed
     * @throws \Exception
     */
    public function migrateImage(string $sourceImageUrl)
    {
        $xmlString = self::generateXMLPayload([
            'Image' => [
                'Url' => $sourceImageUrl
            ]
        ]);
        $this->addApiParam('payload', $xmlString);

        return self::post('/image/migrate');
    }

    /**
     * 使用此API可以将多个图像从外部站点迁移到Lazada站点。允许的图像格式为JPG和PNG。图像文件的最大大小为1MB。每次最多可以迁移8张图像。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/images/migrate
     *
     * @param array $imageUrls [''http://pic4.nipic.com/20091217/3885730_124701000519_2.jpg','http://pic4.nipic.com/20091217/3885730_124701000519_2.jpg']
     *
     * @return mixed
     * @throws \Exception
     */
    public function migrateImages(array $imageUrls)
    {
        if (count($imageUrls) > 8) {
            throw new \Exception('一次最多迁移8张图片', 400);
        }
        $images    = array_map(function ($imageUrl) {
            return [
                'Url' => $imageUrl
            ];
        }, $imageUrls);
        $xmlString = self::generateXMLPayload([
            'Images' => $images
        ]);
        $this->addApiParam('payload', $xmlString);

        return self::post('/images/migrate');
    }

    /**
     * 使用此API可以删除现有产品，一个产品中的某些SKU或一个产品中的所有SKU。系统在一个请求中最多支持50个SellerSkus。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/product/remove
     *
     * @param array $sellerSkuList ["asd","vvv","sss"]
     *
     * @return mixed
     * @throws \Exception
     */
    public function removeProduct(array $sellerSkuList)
    {
        if (count($sellerSkuList) > 50) {
            throw new \Exception('一次最多删除50个SellerSkus', 400);
        }

        $this->addApiParam('seller_sku_list', $sellerSkuList);

        return self::post('/product/remove');
    }

    /**
     * 使用此API，更新商品图片信息，以最后一次提交的为准, 如：原来设置了8张图片，最后一次更新只提交了一张图片则其余的7张图片将被删除。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/images/set
     *
     * @param array $skuImages ['SellerSku'=>['https://cdn.image.net/image1','https://cdn.image.net/image2']]
     *
     * @return mixed
     * @throws \Exception
     */
    public function setImages(array $skuImages)
    {
        $skus = [];
        foreach ($skuImages as $sellerSku => $images) {
            $skus[] = [
                'Sku' => [
                    'SellerSku' => $sellerSku,
                    'Images'    => array_map(function (string $imgUrl) {
                        return [
                            'Image' => $imgUrl
                        ];
                    }, $images)
                ]
            ];
        }
        $payload = [
            'Product' => [
                'Skus' => $skus
            ]
        ];

        $imageXmlString = self::generateXMLPayload($payload);
        $this->addApiParam('payload', $imageXmlString);

        return self::post('/images/set');
    }

    /**
     * 使用此API更新一个或多个现有产品的价格和数量。最多可以更新50个产品，但建议最多20个。
     * 注意：有促销价的更新零售价格必须大于促销的价格。
     *
     * @see     https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/product/price_quantity/update
     *
     * @param array $newPriceQuantityData
     *
     * @return mixed
     * @throws \Exception
     * @example $newPriceQuantityData 单仓库卖家
     * [
     *     'Product' => [
     *        'Skus' => [
     *                [
     *                    'Sku' => [
     *                        'SellerSku' => 'Apple-SG-Glod-64G',
     *                        'Price'     => '1099.00',
     *                        'SalePrice' => '900.00',
     *                        'SaleStartDate' => '2017-08-08',
     *                        'SaleEndDate' => '2017-08-31',
     *                        'Quantity' => '30' // 单仓库卖家设置，多仓库卖家不用给该数据
     *                        'MultiWarehouseInventories' => [ // 多仓库卖家设置，单仓库卖家不要给该数据 *
     *                              [
     *                                  'MultiWarehouseInventory'=> [
     *                                      'WarehouseCode'=> 'warehouseTest1', // 仓库代码
     *                                      'Quantity'=> '30'
     *                                  ]
     *                              ]
     *                        ]
     *                     ]
     *                ]
     *            ]
     *        ]
     * ]
     */
    public function updatePriceQuantity(array $newPriceQuantityData)
    {
        $payloadXml = self::generateXMLPayload($newPriceQuantityData);
        $this->addApiParam('payload', $payloadXml);

        return self::post('/product/price_quantity/update');
    }

    /**
     * 使用此API更新现有产品的属性或SKU
     *
     * @see     https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/product/update
     *
     * @param array $productData 数组key 大小写敏感
     *
     * @return mixed
     * @throws \Exception
     * @example $productData
     * {
     *    "Product": {
     *        "PrimaryCategory": "6576",
     *        "SPUId": "",
     *        "AssociatedSku": "",
     *        "Attributes": {
     *            "name": "Cheese forest Indian children's tent play house children's ",
     *            "brand": "No Brand",
     *            "short_description": "商品描述信息",
     *        },
     *        "Skus": [
     *            {
     *                "Sku": {
     *                    "color_family": "White_Not Specified",
     *                    "size": "Not Specified",
     *                    "SellerSku": "1051-12883-White-Not Specified",
     *                    "price": 0,
     *                    "package_weight": 4,
     *                    "package_length": 160,
     *                    "package_width": 12,
     *                    "package_height": 12,
     *                    "Status": "inactive",
     *                    "quantity": 1111,
     *                    "Images": [
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/5554bc476b8167ed8aeeb9f09d4e1993.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/1172eaa46b28776f9ffe944e3c7d4cd8.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/73ff045b9c71873fc8078a14a1218e76.jpg"
     *                        }
     *                    ]
     *                }
     *            },
     *            {
     *                "Sku": {
     *                    "color_family": "Blue_Not Specified",
     *                    "size": "Not Specified",
     *                    "SellerSku": "1051-12883-Blue-Not Specified",
     *                    "price": 0,
     *                    "package_weight": 4,
     *                    "package_length": 160,
     *                    "package_width": 12,
     *                    "package_height": 12,
     *                    "Status": "inactive",
     *                    "quantity": 1111,
     *                    "Images": [
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/5554bc476b8167ed8aeeb9f09d4e1993.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/1172eaa46b28776f9ffe944e3c7d4cd8.jpg"
     *                        },
     *                        {
     *                            "Image": "https://my-live-02.slatic.net/p/73ff045b9c71873fc8078a14a1218e76.jpg"
     *                        }
     *                    ]
     *                }
     *            }
     *        ]
     *    }
     *}
     */
    public function updateProduct(array $productData)
    {
        $payloadXml = self::generateXMLPayload($productData);
        $this->addApiParam('payload', $payloadXml);

        return $this->post('/product/update');
    }

    /**
     * 使用此API将单个图像文件上传到Lazada网站。允许的图像格式为JPG和PNG。图像文件的最大大小为1MB。
     *
     * @see https://open.lazada.com/doc/api.htm?spm=a2o9m.11193531.0.0.2c3d6bbe6GdZ0B#/api?cid=5&path=/image/upload
     *
     * @param string $imageFilePath ./image.png
     *
     * @return mixed
     * @throws \Exception
     */
    public function uploadImage(string $imageFilePath)
    {
        if (file_exists($imageFilePath)) {
            $options = [
                'multipart' => [
                    [
                        'name'     => 'image',
                        'contents' => fopen($imageFilePath, 'r')
                    ]
                ]
            ];

            return self::post('/image/upload', $options);
        }
    }
}